package com.smart.mattress.account.server.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.gridfs.GridFSDBFile;
import com.smart.mattress.account.dao.UserInfoDao;
import com.smart.mattress.account.mail.EmailServer;
import com.smart.mattress.account.redis.RedisUtil;
import com.smart.mattress.account.server.FileStoreService;
import com.smart.mattress.account.server.UserInfoService;
import com.smart.mattress.common.model.account.ConcernInfo;
import com.smart.mattress.common.model.account.DeviceInfo;
import com.smart.mattress.common.model.account.UserInfo;
import com.smart.mattress.common.model.result.ResultData;
import com.smart.mattress.common.tool.MD5Tools;



/**
 * 用户信息管理模块
 * Created by rencong on 17/3/10.
 */
@Service
public class UserInfoServiceImpl implements UserInfoService {


    Logger logger = LoggerFactory.getLogger(UserInfoServiceImpl.class);

    @Autowired
    UserInfoDao userInfoDao;
    @Autowired
    EmailServer emailServer;
    @Autowired
    FileStoreService fileStoreService;
    
    private Query device_query = new Query();

	@Autowired
    private RedisUtil redisUtil;
    
    private UserInfo userInfo;

    @Override
    public JSONObject login(String email, String password) {

        logger.info("user login email:{},password:{}",email,password);

        JSONObject jsonData = new JSONObject();
        
        Query query = new Query();
        Pattern pattern = Pattern.compile("^"+email+"$",Pattern.CASE_INSENSITIVE);
        query.addCriteria(Criteria.where("email").regex(pattern).and("password").is(MD5Tools.MD5(password)));
       logger.info("login select:{}",query.toString());
        //query.addCriteria(Criteria.where("email").is(email).and("password").is(MD5Tools.MD5(password)));
        
        //判断用户是否存在
        long flog = checkExist(email,UserInfo.class,"UserInfo");
        if(flog == 0){
        	return ResultData.mobileResult(1001,"noUser",null);
        }
        
        UserInfo result = (UserInfo) userInfoDao.findOneByQuery(query,UserInfo.class,"UserInfo");
        
        if(result != null){
        	boolean flog_flog = true;
        	String newFileName = null;
        	String token = null;
        	String t_token = String.valueOf(result.getUserId()) + String.valueOf(System.currentTimeMillis());
	         token = MD5Tools.MD5(t_token);
	         redisUtil.set(token,result.getUserId(),864000l);//token,UserId,10天
	         String oldFileName = null;
             jsonData.put("token", token);
             jsonData.put("userInfo", result);
             return ResultData.mobileResult(1,"Successfully",jsonData);
        }else{
        	 return ResultData.mobileResult(1000,"Error",null);//用户名或密码错误
        }

    }
    
    @Override
    public String register(UserInfo userInfo){
    	
    	//1、重复性判断
    	long flog = checkExist(userInfo.getEmail(),UserInfo.class,"UserInfo");
    	if(flog > 0){
    		return "repeat";
    	}
    	
    	//2、拼接userInfo
    	//生成唯一userID,当前纳秒数(15位)加上用UUID的hashcode的3位
    	String uId = String.valueOf(System.nanoTime())+String.valueOf(UUID.randomUUID().hashCode()).substring(1,4);
    	//String uId = String.valueOf(System.nanoTime());
    	userInfo.setUserId(Long.parseLong(uId));
    	
    	userInfo.setCreateTime(System.currentTimeMillis());

    	userInfo.setPassword(MD5Tools.MD5(userInfo.getPassword()));
    	
    	//3、用户注册
    	boolean ret = userInfoDao.add(userInfo,"UserInfo");
    	
    	if(ret){
    		return "success";
    	}else{
    		return "fail";
    	}
    	
    }
    
    @Override
    public boolean modify(UserInfo userInfo){
    	
    	userInfo.setPassword(MD5Tools.MD5(userInfo.getPassword()));
    	
    	Query query = new Query();
        query.addCriteria(Criteria.where("email").is(userInfo.getEmail()));
        UserInfo currentInfo = (UserInfo) userInfoDao.findOneByQuery(query, UserInfo.class,"UserInfo");
        userInfo.setUserId(currentInfo.getUserId());
        JSONObject json = userInfo.getBirthDay();
        Update up = Update.update("password", userInfo.getPassword()).set("firstName", userInfo.getFirstName())
        				  .set("middleName", userInfo.getMiddleName()).set("lastName", userInfo.getLastName())
        				  .set("birthDay", json).set("gender", userInfo.getGender())
        				  .set("address", userInfo.getAddress()).set("mphone", userInfo.getMphone())
        				  .set("image", userInfo.getImage()).set("userId", userInfo.getUserId());
    	
    	return userInfoDao.update(query, up, UserInfo.class,"UserInfo");
    }
    
    @Override
    public boolean forget(String email,HttpServletRequest req){
    	
    	//检查存在性
    	long flog = checkExist(email,UserInfo.class,"UserInfo");
    	if(flog > 0){
    		//用UUID的前8位当做验证码
    		String verifi = UUID.randomUUID().toString().substring(0,8);
    		emailServer.send(email,"18861824097@sina.cn","Verification Code",verifi);
    		//在redis中存放验证码，验证次数
    		redisUtil.set(email, verifi,600l);
    		redisUtil.set(email+"count_num", 0);
    		
    		return true;
    	}else{
    		return false;
    	}
    	
    	
    }
    
    @Override
    public boolean modifyPwd(UserInfo userInfo){
    	
    	userInfo.setPassword(MD5Tools.MD5(userInfo.getPassword()));
    	
    	//先查出该用户的id
    	Query query = new Query();
    	if(userInfo.getEmail() != null){
    		query.addCriteria(Criteria.where("email").is(userInfo.getEmail()));
    	}else{
    		query.addCriteria(Criteria.where("userId").is(userInfo.getUserId()));
    	}
    	Update up = Update.update("password",userInfo.getPassword());
    	
    	return userInfoDao.update(query, up, UserInfo.class,"UserInfo");
    }
    
    @Override
    public UserInfo getInfo(String token){
    	
    	Query query = new Query();
    	query.addCriteria(Criteria.where("userId").is(redisUtil.get(token)));
    	UserInfo userInfo = (UserInfo) userInfoDao.findOneByQuery(query,UserInfo.class,"UserInfo");
    	boolean flog_flog = true;
    	String newFileName = null;
    	 try {
             String oldFileName = null;
             if(userInfo.getImage()!=null && userInfo.getImage()!="" &&userInfo.getImage()!=" " && userInfo.getImage().length()>32){
            	 oldFileName = userInfo.getImage().substring(32,userInfo.getImage().length());
             }
             //随机码 让客户端判断是否做过修改
     		 String random = String.valueOf(UUID.randomUUID().hashCode()).substring(2,6);
             StringBuffer image_path = new StringBuffer("/root/tomcat/apache-tomcat-7.0.77/webapps/head/");
             newFileName = userInfo.getUserId()+random+".png";
             image_path.append(newFileName);
             File image = new File(image_path.toString());
             //logger.warn("image_user:{}",String.valueOf(userInfo.getUserId()));
             GridFSDBFile sFile = fileStoreService.findByFileName(String.valueOf(userInfo.getUserId()));
             if(!image.exists()){
                	 image.createNewFile();
                 }
            	 if(sFile==null){
            		 userInfo.setImage("");
            		 flog_flog = false;
            	 }else{
            		 sFile.writeTo(image);
            	 }
            	 if(flog_flog)
                	 userInfo.setImage("http://101.37.100.209:9001/login/getPic?user="+newFileName);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    	 
    	Update up = Update.update("password", userInfo.getPassword()).set("firstName", userInfo.getFirstName())
				  .set("middleName", userInfo.getMiddleName()).set("lastName", userInfo.getLastName())
				  .set("birthDay", userInfo.getBirthDay()).set("gender", userInfo.getGender())
				  .set("address", userInfo.getAddress()).set("mphone", userInfo.getMphone())
				  .set("image", userInfo.getImage()).set("userId", userInfo.getUserId());
    	userInfoDao.update(query, up, UserInfo.class,"UserInfo");
    	return userInfo;
    }
    
    @Override
    public UserInfo queryUser(String email){
    	Pattern pattern = Pattern.compile("^"+email+"$",Pattern.CASE_INSENSITIVE);
    	Query query = new Query();
    	query.addCriteria(Criteria.where("email").regex(pattern));
    	return (UserInfo) userInfoDao.findOneByQuery(query,UserInfo.class,"UserInfo");
    }
    
    @Override
    public String applyConcern(String token,String email){
    	boolean flog;
    	//1、根据email，检查要关注的对象是否存在
    	long ret = checkExist(email,UserInfo.class,"UserInfo");
    	if(ret == 0){
    		return "noUser";
    	}
    	
    	//2、查询发出申请的用户的email,当前用户
    	UserInfo result = (UserInfo) getInfoByToken(token,UserInfo.class,"UserInfo");
    	
    	if(email.equals(result.getEmail())){
    		return "self";
    	}
    	
    	//3、检查关注表，查看是否已经关注过
    	Query query = new Query();
    	query.addCriteria(Criteria.where("applyEmail").is(email).and("currentEmail").is(result.getEmail()).and("status").is(0));
    	long number1 = userInfoDao.count(query,ConcernInfo.class,"ConcernInfo");
    	//未申请过关注，或者对方拒绝的情况下才可以继续申请
    	if(number1 > 0){
    		return "repeat";
    	}
    	Query query1 = new Query();
    	query1.addCriteria(Criteria.where("applyEmail").is(email).and("currentEmail").is(result.getEmail()).and("status").is(1));
    	long number = userInfoDao.count(query1,ConcernInfo.class,"ConcernInfo");
    	//未申请过关注，或者对方拒绝的情况下才可以继续申请
    	if(number > 0){
    		return "repeat";
    	}
    	

		ConcernInfo concernInfo = new ConcernInfo();

    	//4、拼接申请信息
    	concernInfo.setApplyEmail(email);
    	concernInfo.setCurrentEmail(result.getEmail());
    	concernInfo.setApplyTime(new Date().getTime());
    	concernInfo.setStatus(0);
    	
    	//5、申请信息入表
    	flog = userInfoDao.add(concernInfo,"ConcernInfo");
    	
    	if(!flog){
    		return "fail";
    	}
    	return "success";
    }
    
    @Override
    public String handleConcern(String token,String email,String handle){
    	
    	UserInfo ret = new UserInfo();
    	
    	//1、查出当前用户的信息
    	UserInfo result = (UserInfo) getInfoByToken(token,UserInfo.class,"UserInfo");
    	
    	boolean flog = true;
    	//3、更新关注信息
    	if("agree".equals(handle)){
    		
    		List concernMe = result.getFollower();
    		if( concernMe != null && concernMe.size()!=0){
    			Iterator it = concernMe.iterator();
    			while(it.hasNext()){
    				if(email.equals((String)it.next())){
    					return "repeat";
    				}
    			}
    		}
    		
    		//更新关注表
    		Query query = new Query();
        	query.addCriteria(Criteria.where("currentEmail").is(email).and("applyEmail").is(result.getEmail()).and("status").is(0));
    		Update up = Update.update("status", 1);
    		flog = userInfoDao.update(query, up, ConcernInfo.class,"ConcernInfo");
    		if(!flog){
    			return "false";
    		}
    		
    		//更新当前用户信息 关注我
    		List list1 = new ArrayList();
    		if(result.getFollower()==null){
    			list1 = new ArrayList();
    		}else{
    			list1 = result.getFollower();
    		}
    		list1.add(email);
    		Query query1 = new Query();
        	query1.addCriteria(Criteria.where("email").is(result.getEmail()));
        	Update up1 = Update.update("follower", list1);
        	flog =userInfoDao.update(query1, up1, UserInfo.class,"UserInfo");
    		if(!flog){
    			return "false";
    		}
        	
    		//更新对方信息 我的关注
        	List list2 = new ArrayList();
        	Query query2 = new Query();
        	query2.addCriteria(Criteria.where("email").is(email));
        	ret = (UserInfo) userInfoDao.findOneByQuery(query2,UserInfo.class,"UserInfo");
        	if(ret.getFocus()==null){
    			list2 = new ArrayList();
    		}else{
    			list2 = ret.getFocus();
    		}
        	list2.add(result.getEmail());
        	Update up2 = Update.update("focus", list2);
        	
        	flog = userInfoDao.update(query2, up2, UserInfo.class,"UserInfo");
        	if(!flog){
    			return "false";
    		}
        	
    	}else{
    		//更新关注表
    		Query query4 = new Query();
        	query4.addCriteria(Criteria.where("currentEmail").is(email).and("applyEmail").is(result.getEmail()));
    		flog = userInfoDao.remove(query4, ConcernInfo.class,"ConcernInfo");
    		if(!flog){
    			return "false";
    		}
    	}
    	return "true";
    }
    
    @Override
    public boolean cancelConcern(String token,String email,String type){
    	
    	//1、查询信息
    	//先找出自己的信息
    	UserInfo result = (UserInfo) getInfoByToken(token,UserInfo.class,"UserInfo");
    	//用作更新自己信息
    	Query query = new Query();
    	query.addCriteria(Criteria.where("email").is(result.getEmail()));
    	
    	//找出对方的信息 同时用于更新对方信息
    	Query query1 = new Query();
    	query1.addCriteria(Criteria.where("email").is(email));
    	UserInfo ret = (UserInfo) userInfoDao.findOneByQuery(query1,UserInfo.class,"UserInfo");
    	
    	//2、更新信息 
    	//用来更新关注表
    	Query query2 = new Query();
    	
    	Update update1 = new Update();
    	Update update2 = new Update();
    	if("myConcern".equals(type)){
    		
    		query2.addCriteria(Criteria.where("currentEmail").is(result.getEmail())
    								.and("applyEmail").is(email));
    		
    		List list1 = new ArrayList();
    		list1 = result.getFocus();
    		list1.remove(email);
    		List list2 = new ArrayList();
    		list2 = ret.getFollower();
    		list2.remove(result.getEmail());
    		
    		update1 = Update.update("focus", list1);
    		update2 = Update.update("follower", list2);
    	}else{
    		
    		query2.addCriteria(Criteria.where("currentEmail").is(email)
								.and("applyEmail").is(result.getEmail()));
    		
    		List list1 = new ArrayList();
    		list1 = result.getFollower();
    		list1.remove(email);
    		List list2 = new ArrayList();
    		list2 = ret.getFocus();
    		list2.remove(result.getEmail());
    		update1 = Update.update("follower", list1);
    		update2 = Update.update("focus", list2);
    	}
    	
    	
    	if(userInfoDao.update(query, update1, UserInfo.class,"UserInfo")){
    		if(userInfoDao.update(query1, update2, UserInfo.class,"UserInfo")){
    			return userInfoDao.remove(query2, ConcernInfo.class, "ConcernInfo");
    		}else{
    			return false;
    		}
    	}else{
    		return false;
    	}
    	
    }
    
    @Override
    public List getWait(String token){
    	
    	List info_lists = new ArrayList();
    	
    	//找出自己的信息
    	UserInfo result = (UserInfo) getInfoByToken(token,UserInfo.class,"UserInfo");
    	
    	//查出待批准列表
    	Query query = new Query();
    	query.addCriteria(Criteria.where("applyEmail").is(result.getEmail()).and("status").is(0));
    	List list = userInfoDao.findListByQuery(query, ConcernInfo.class, "ConcernInfo");
    	
    	//批准信息封装
    	Iterator<ConcernInfo> it = list.iterator();
    	while(it.hasNext()){
    		Query query1 = new Query();
    		query1.addCriteria(Criteria.where("email").is(it.next().getCurrentEmail()));
    		UserInfo user = (UserInfo) userInfoDao.findOneByQuery(query1, UserInfo.class, "UserInfo");
    		JSONObject info_list = new JSONObject();
    		info_list.put("image", user.getImage());
    		info_list.put("name", user.getFirstName()+" "+(user.getMiddleName() == null?"":(user.getMiddleName()+" "))+user.getLastName());
    		info_list.put("email", user.getEmail());
    		info_list.put("gender", user.getGender());
    		
    		info_lists.add(info_list);
    	}
    	
    	return info_lists;
    }
    
    @Override
    public List getMyConcern(String token){
    	
    	List info_lists = new ArrayList();
    	
    	//找出自己的信息
    	UserInfo result = (UserInfo) getInfoByToken(token,UserInfo.class,"UserInfo");
    	if(result == null){
    		return null;
    	}
    	
    	List list = result.getFocus();
    	if(list==null){
    		return info_lists;
    	}
    	int i =0;
    	Iterator<String> it = list.iterator();
    	while(it.hasNext()){
    		Query query1 = new Query();
    		query1.addCriteria(Criteria.where("email").is(it.next()));
    		UserInfo user = (UserInfo) userInfoDao.findOneByQuery(query1, UserInfo.class, "UserInfo");
    		JSONObject info_list = new JSONObject();
    		info_list.put("image", user.getImage());
    		info_list.put("name", user.getFirstName()+" "+(user.getMiddleName() == null?"":(user.getMiddleName()+" "))+user.getLastName());
    		info_list.put("email", user.getEmail());
    		info_list.put("gender", user.getGender());
    		info_list.put("device", user.getDevice());
    		info_lists.add(info_list);
    	}
    	
    	return info_lists;
    }
    
    @Override
    public List getConcernMe(String token){
    	
    	List info_lists = new ArrayList();
    	
    	//找出自己的信息
    	UserInfo result = (UserInfo) getInfoByToken(token,UserInfo.class,"UserInfo");
    	
    	if(result == null){
    		return null;
    	}
    	List list = result.getFollower();
    	
    	if(list==null){
    		return info_lists;
    	}
    	
    	Iterator<String> it = list.iterator();
    	while(it.hasNext()){
    		Query query1 = new Query();
    		query1.addCriteria(Criteria.where("email").is(it.next()));
    		UserInfo user = (UserInfo) userInfoDao.findOneByQuery(query1, UserInfo.class, "UserInfo");
    		JSONObject info_list = new JSONObject();
    		info_list.put("image", user.getImage());
    		info_list.put("name", user.getFirstName()+" "+(user.getMiddleName() == null?"":(user.getMiddleName()+" "))+user.getLastName());
    		info_list.put("email", user.getEmail());
    		info_list.put("gender", user.getGender());
    		
    		
    		info_lists.add(info_list);
    	}
    	
    	return info_lists;
    }
    
    
    @Override
    public long checkExist(String email,Class infoClass,String collectionName){
    	Query query = new Query();
    	Pattern pattern = Pattern.compile("^"+email+"$",Pattern.CASE_INSENSITIVE);
        query.addCriteria(Criteria.where("email").regex(pattern));
    	//query.addCriteria(Criteria.where("email").is(email));
        return userInfoDao.count(query,infoClass,collectionName);
    }
    
    /**
     * 根据token查询出对应的对象，UserInfo，ConcernInfo
     * @param token
     * @param infoClass
     * @param collectionName
     * @return
     */
    @Override
    public Object getInfoByToken(String token,Class infoClass,String collectionName){

		logger.info("token:{},collection name:{}",token,collectionName);


		long userId = 0l;

		try{
			userId = (Long) redisUtil.get(token);
		}catch (Exception e){
			logger.error("get info by token error",e);
		}

    	Query query = new Query();
    	query.addCriteria(Criteria.where("userId").is(userId));

    	return userInfoDao.findOneByQuery(query,infoClass,collectionName);
    }
    
    /**
     * 每隔30s将设备信息更新一下
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void infoUpdate(){
    	

    	List<DeviceInfo> list = userInfoDao.findListByQuery(new Query(), DeviceInfo.class, "DeviceInfo");
		//logger.info("更新设备和用户对应关系,{}", JSON.toJSON(list));
    	for(DeviceInfo obj:list){
			logger.info("设备sn:{},userid:{}",obj.getDeviceSN(),String.valueOf(obj.getUserid()));
    		redisUtil.setObject("device_userid_"+obj.getDeviceSN(),String.valueOf(obj.getUserid()),60);
    	}

		/*redisUtil.set("ddddddd",1234567890l);

		String i = String.valueOf(redisUtil.get("ddddddd"));

		System.out.println(i);*/



    	
    }
    
    /**
     * 更新std228@126.com
     * @param email
     */
    @Override
    public void updateSuperAccount(String email){
    	logger.info("SuperAccount Add:{}",email);
    	Query query = new Query();
		query.addCriteria(Criteria.where("email").is("std228@126.com"));
		UserInfo user = (UserInfo) userInfoDao.findOneByQuery(query, UserInfo.class, "UserInfo");
		List list_focus = new ArrayList();
		if(user.getFocus()!=null){
			list_focus = user.getFocus();
		}
		list_focus.add(email);
		Update update = Update.update("focus", list_focus);
		userInfoDao.update(query, update, UserInfo.class,"UserInfo");
		
    }
}
